home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 55375 / 55375.xpi / components / btMetricsLiteService.js < prev   
Text File  |  2009-11-15  |  12KB  |  371 lines

  1. const Cc = Components.classes;
  2. const Ci = Components.interfaces;
  3.  
  4. Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
  5. try {
  6.   Components.utils.import("resource://gre/modules/JSON.jsm");
  7.   JSON.stringify = JSON.toString;
  8. } catch (ex) {
  9.   /* Firefox 3.1 has native JSON support */
  10. }
  11.  
  12. const gPrefService = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefService);
  13. const gPrefBranch = gPrefService.getBranch(null).QueryInterface(Ci.nsIPrefBranch2);
  14. const gObserver = Cc['@mozilla.org/observer-service;1'].getService(Ci.nsIObserverService);
  15. const gConsoleService = Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService);
  16. const gXULAppInfo = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo);
  17. const gXULRuntime = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULRuntime);
  18. const gExtensionManager = Cc["@mozilla.org/extensions/manager;1"].getService(Ci.nsIExtensionManager);
  19.  
  20. function BTMetricsLite() {
  21. }
  22.  
  23. BTMetricsLite.prototype = {
  24.     debug: false,
  25.     serverURI: '',
  26.     enabled: false,
  27.     bid: '',
  28.     browserVersion: 0,
  29.     extensionVersion: '',
  30.     os: '',
  31.     mDBConn: null,
  32.     timer: null,
  33.     sbServices: {
  34.         YAHOO_SB_SERVICE: 1,
  35.         ASK_SB_SERVICE: 2
  36.     },
  37.     request: null,
  38.  
  39.     observe: function(aSubject, aTopic, aData) {
  40.         switch(aTopic) {
  41.             case "app-startup":
  42.                 gObserver.addObserver(this,"profile-after-change",false);
  43.                 gObserver.addObserver(this,"profile-before-change",false);
  44.                 gObserver.addObserver(this,"xpcom-shutdown",false);
  45.                 gObserver.addObserver(this,"final-ui-startup",false);
  46.                 break;
  47.             case "xpcom-shutdown":
  48.                 gObserver.removeObserver(this,"profile-after-change");
  49.                 gObserver.removeObserver(this,"profile-before-change");
  50.                 gObserver.removeObserver(this,"final-ui-startup");
  51.                 gObserver.removeObserver(this,"xpcom-shutdown");
  52.                 break;
  53.             case "profile-before-change":
  54.                 this.packageData(false);
  55.                 break;
  56.             case "final-ui-startup":
  57.                 gObserver.addObserver(this, "brandthunder", false);
  58.                 this.init();
  59.                 break;
  60.             case "brandthunder":
  61.                 var currentBoom = "";
  62.                 try {
  63.                     currentBoom = this.getPref('extensions.brandthunder.currentBoom');
  64.                 } catch (ex) {}
  65.                 var brandObject = aSubject.wrappedJSObject;
  66.                 /* Need to accomodate old code */
  67.                 if (brandObject.booms) {
  68.                     /* If the currentBoom isn't in the brand Object we were given, */
  69.                     /* use the client short name */
  70.                     if (!brandObject.booms[currentBoom]) {
  71.                         currentBoom = brandObject.shortName;
  72.                     }
  73.                 }
  74.                 
  75.                 if (aData == "active") {
  76.                     this.extensionVersion = gExtensionManager.getItemForID(brandObject.extensionID).version;
  77.                     this.sendActiveStatus(currentBoom);
  78.                 } else {
  79.                     this.storeAction(currentBoom, aData);
  80.                 }
  81.                 return;
  82.         }
  83.     },
  84.     notify: function(timer) {
  85.         this.packageData(true);    
  86.     },
  87.     init: function() {
  88.         var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
  89.         if (env.get('BRANDTHUNDER')) {
  90.             this.debug = true;
  91.         }
  92.  
  93.         this.enabled = this.getPref('extensions.btMetricsLite.enabled');
  94.         this.serverURI = this.getPref('extensions.btMetricsLite.uri');
  95.         var env = Cc['@mozilla.org/process/environment;1'].getService(Ci.nsIEnvironment);
  96.         if (this.debug) {
  97.             this.serverURI = 'https://btmetrics-dev.brandthunder.com/service';
  98.         }
  99.         if (!this.getPref('extensions.btMetricsLite.bid')) {
  100.             this.setPref('extensions.btMetricsLite.bid', this.generateBid());
  101.         }
  102.         this.bid = this.getPref('extensions.btMetricsLite.bid');
  103.         this.browserVersion = gXULAppInfo.version.match(/(\d+\.\d+)/)[1].replace('.', '');
  104.         this.os = gXULRuntime.OS;
  105.         
  106.         this.timer = Components.classes['@mozilla.org/timer;1'].createInstance(Components.interfaces.nsITimer);
  107.         if (this.debug) {
  108.             this.timer.initWithCallback(this, 30000, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  109.         } else {
  110.             this.timer.initWithCallback(this, 300000, Components.interfaces.nsITimer.TYPE_REPEATING_SLACK);
  111.         }
  112.  
  113.         var database = Components.classes['@mozilla.org/file/directory_service;1']
  114.                                      .getService(Components.interfaces.nsIProperties)
  115.                                      .get('ProfD', Components.interfaces.nsIFile);
  116.         database.append('btmetricslite.sqlite');
  117.         this.mDBConn = Components.classes['@mozilla.org/storage/service;1'].getService(Components.interfaces.mozIStorageService).openDatabase(database);
  118.             
  119.         this.sqlToObj("CREATE TABLE IF NOT EXISTS 'events' ('cid' VARCHAR(255) NOT NULL, 'action' VARCHAR(255) NOT NULL, 'created' DATETIME NOT NULL)");
  120.     },
  121.     getPref: function(name, defaultVal) {
  122.         try {
  123.             switch (gPrefBranch.getPrefType(name)) {
  124.                 case 32: //string
  125.                     return  gPrefBranch.getCharPref(name);
  126.                 case 64: //int
  127.                     return gPrefBranch.getIntPref(name);
  128.                 case 128: //bool
  129.                     return gPrefBranch.getBoolPref(name);
  130.             }
  131.         } catch (e) {
  132.         }
  133.         return defaultVal;
  134.     },
  135.  
  136.     setPref: function(name, val) {
  137.         if ((val === true) || (val === false)){
  138.             gPrefBranch.setBoolPref(name, val);
  139.         } else if (typeof val == 'string'){
  140.             gPrefBranch.setCharPref(name, val);
  141.         } else {
  142.             gPrefBranch.setIntPref(name, val);
  143.         }
  144.     },
  145.  
  146.     md5: function(str) {
  147.         var converter = Cc['@mozilla.org/intl/scriptableunicodeconverter'].createInstance(Ci.nsIScriptableUnicodeConverter);
  148.         converter.charset = 'UTF-8';
  149.         var result = {};
  150.         var data = converter.convertToByteArray(str, result);
  151.         var ch = Cc['@mozilla.org/security/hash;1'].createInstance(Ci.nsICryptoHash);
  152.         ch.init(ch.MD5);
  153.         ch.update(data, data.length);
  154.         var hash = ch.finish(false);
  155.         
  156.         function toHexString(charCode) {
  157.             return ('0' + charCode.toString(16)).slice(-2);
  158.         }
  159.      
  160.         var s = [toHexString(hash.charCodeAt(i)) for (i in hash)].join('');
  161.      
  162.         return s;
  163.     },
  164.     timestamp: function(_131) {
  165.         var d = new Date();
  166.         var _133 = d.getTime();
  167.         var time = _133/1000;
  168.         var _135 = parseInt(time);
  169.         return (_131) ? time : _135;
  170.     },
  171.     generateBid: function() {
  172.         return this.md5(this.timestamp(true) + ':' + Math.random());
  173.     },
  174.         
  175.     storeAction: function(shortName, action) {
  176.         if (this.enabled) {
  177.             var localdate = new Date();
  178.             try {
  179.                 this.sqlToObj("INSERT INTO events " +
  180.                                              "(cid, action, created) " +
  181.                                              "VALUES " +
  182.                                              "('" + this.dbClean(shortName) + "', '" + this.dbClean(action) + "', '" + this.toTimeString(localdate) + "')");
  183.             } catch (e) {}
  184.         }
  185.     },
  186.                 
  187.     sendActiveStatus: function(currentBoom) {
  188.         var currentdate = new Date();
  189.         var currenttimestamp = currentdate.getTime() / 1000;
  190.         
  191.         var lastsent = this.getPref('extensions.btMetricsLite.lastsent');
  192.         if (lastsent) {
  193.             if ((currenttimestamp - lastsent) < 3600) {
  194.                 if (!this.debug) {
  195.                     return;
  196.                 }
  197.             }
  198.         }
  199.             
  200.         var searchSvc = Cc['@mozilla.org/browser/search-service;1']
  201.                                         .getService(Ci.nsIBrowserSearchService);
  202.         
  203.         if (searchSvc.currentEngine.description == "Yahoo! - BT") {
  204.             searchService = this.sbServices.YAHOO_SB_SERVICE;
  205.         } else if (searchSvc.currentEngine.description == "Ask - BT") {
  206.             searchService = this.sbServices.ASK_SB_SERVICE;
  207.         } else {
  208.             searchService = 0;
  209.         }
  210.         
  211.         this.sendData('active=1&cid=' + currentBoom + '&bid=' + this.bid + '&bv=' + this.browserVersion + '&os=' + this.os + '&ev=' + this.extensionVersion + '&sbs=' + searchService, false, true);
  212.         this.setPref('extensions.btMetricsLite.lastsent', currenttimestamp);
  213.     },
  214.  
  215.                 
  216.     toTimeString: function(localdate) {
  217.         return this.toDateString(localdate, 'y-m-d h:i:s', true);
  218.     },
  219.         
  220.     toDateString: function(localdate, format, showZeros) {
  221.         var gmt = localdate.getTime() + (localdate.getTimezoneOffset() * 60000);
  222.         var date = new Date(gmt);
  223.         
  224.         format = format.toLowerCase();
  225.         
  226.         // cast all values to strings
  227.         var day = '' + date.getDate(),
  228.             month = '' + (date.getMonth() + 1),
  229.             hour = '' + date.getHours(),
  230.             minute = '' + date.getMinutes(),
  231.             second = '' + date.getSeconds(),
  232.             year = '' + date.getFullYear();
  233.         
  234.         // pad leading zeros
  235.         if (showZeros) {
  236.             if (1 === day.length) {day = '0' + day;}
  237.             if (1 === month.length) {month = '0' + month;}
  238.             if (1 === hour.length) {hour = '0' + hour;}
  239.             if (1 === minute.length) {minute = '0' + minute;}
  240.             if (1 === second.length) {second = '0' + second;}
  241.         }
  242.         
  243.         return format.replace('y', year)
  244.                      .replace('d', day)
  245.                      .replace('h', hour)
  246.                      .replace('i', minute)
  247.                      .replace('s', second)
  248.                      .replace('m', month); // do month last as some months contain reserved letters
  249.     },
  250.     
  251.     clearTime: function(date) {
  252.         date.setHours(0);
  253.         date.setMinutes(0);
  254.         date.setSeconds(0);
  255.         date.setMilliseconds(0);
  256.         
  257.         return date;
  258.     },
  259.              
  260.                 
  261.     packageData: function(async) {
  262.         var dbObject = this.sqlToObj("SELECT * FROM events");
  263.         if (dbObject.length > 0) {
  264.             jsonString = JSON.stringify(dbObject);
  265.             var this_ptr = this;
  266.             this.sendData('bid=' + this.bid + '&ev=' + this.extensionVersion + '&events=' + jsonString, function(responseText) {
  267.                 this_ptr.sqlToObj("DELETE FROM events");
  268.             }, async);
  269.             
  270.             //temporary measure to make sure that the sqllite db is cleared on browser close
  271.             if (!async) {
  272.                 this.sqlToObj("DELETE FROM events");
  273.             }
  274.         }
  275.     },
  276.  
  277.     sendData: function(data, callback, async) {
  278.         this.request = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"].createInstance(Ci.nsIXMLHttpRequest);
  279.         this.request.onreadystatechange = function() {
  280.             if (this.readyState == 4) {
  281.                 if (callback) {
  282.                     callback(this.responseText);
  283.                 }
  284.             }
  285.         };
  286.             
  287.         this.request.open('POST', this.serverURI, async);
  288.         this.request.setRequestHeader('Connection', 'close');
  289.         this.request.setRequestHeader('Keep-Alive', '');
  290.         this.request.setRequestHeader('Content-Length', data.length);
  291.         this.request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  292.         this.request.send(data);
  293.     },
  294.  
  295.     sqlToObj: function(sql, matches) {
  296.         var rs, error = false, eMessage;
  297.         if (matches == null) {
  298.             matches = [];
  299.         }
  300.  
  301.         var i, cols, ret, row = 0;
  302.         ret = [];
  303.         var statement = this.mDBConn.createStatement(sql);
  304.         var binds = false;
  305.         while (matches.length > 0) {
  306.             binds = true;
  307.             thisMatch = matches.pop();
  308.             if (thisMatch[0] == 'UTF8String') {
  309.                 statement.bindUTF8StringParameter(matches.length, thisMatch[2]);
  310.             } else if (thisMatch[0] == 'Int32') {
  311.                 statement.bindInt32Parameter(matches.length, thisMatch[2]);
  312.             } else if (thisMatch[0] == 'Blob') {
  313.                 statement.bindBlobParameter(matches.length, thisMatch[2]);
  314.             }
  315.         }
  316.         while (statement.executeStep()) {
  317.             cols = statement.columnCount;
  318.             ret[row] = new Object();
  319.             for (i = 0; i < cols; i++) {
  320.                 var mytype = statement.getTypeOfIndex(i);
  321.                 var myval;
  322.                 if (mytype == statement.VALUE_TYPE_NULL) {
  323.                     myval = statement.getIsNull(i);
  324.                 } else if (mytype == statement.VALUE_TYPE_INTEGER) {
  325.                     myval = statement.getInt32(i);
  326.                 } else if (mytype == statement.VALUE_TYPE_FLOAT) {
  327.                     myval = statement.getDouble(i);
  328.                 } else if (mytype == statement.VALUE_TYPE_TEXT) {
  329.                     myval = statement.getUTF8String(i);
  330.                 } else if (mytype == statement.VALUE_TYPE_BLOB) {
  331.                     myval = statement.getBlob(i);
  332.                 } else {
  333.                     myval = null;
  334.                 }
  335.                 ret[row][statement.getColumnName(i)] = myval;
  336.             }
  337.             row++;
  338.         }
  339.         statement.reset();
  340.         statement = null;
  341.  
  342.         return ret;
  343.     },
  344.  
  345.     dbClean: function(str) {
  346.         var pairs = [["'", "''"]];
  347.         for (var i = 0; i < pairs.length; i++) {
  348.             str = str.split(pairs[i][0]).join(pairs[i][1]);
  349.         }
  350.  
  351.         return str;
  352.     },
  353.  
  354.     log: function(string) {
  355.         gConsoleService.logStringMessage(string);
  356.     },
  357.  
  358.     classDescription: "Brand Thunder Metrics Lite",
  359.     contractID: "@brandthunder.com/btmetricslite;1",
  360.     classID: Components.ID("{5b578c72-d669-4ea9-8d9a-d049d6ade22c}"),
  361.     QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver, Ci.nsITimerCallback]),
  362.     _xpcom_categories: [{
  363.         category: "app-startup",
  364.         service: true
  365.     }]
  366. }
  367.  
  368. function NSGetModule(compMgr, fileSpec) {
  369.     return XPCOMUtils.generateModule([BTMetricsLite]);
  370. }
  371.